﻿namespace Sai.Core.Rules
{
	using Sai.Core.Introspection;

    public class BaseTypeChangeMessageProvider : IMessageProvider
    {
        public BaseTypeChangeMessageProvider(TypeName was)
        {
            this.Was = was;
            this.IsNow = null;
        }

        public BaseTypeChangeMessageProvider(TypeName was, TypeName isNow)
        {
            this.Was = was;
            this.IsNow = isNow;
        }

        public TypeName Was
        {
            get;
            set;
        }

        public TypeName IsNow
        {
            get;
            set;
        }

        public string Message
        {
            get 
            {
                if (this.IsNow == null)
                    return string.Format("Type no longer derived from {0}.", this.Was.ToString());

                return string.Format("Base type changed from {0} to {1}", this.Was.ToString(), this.IsNow.ToString());
            }
        }
    }

	public class CheckTypeDerivation : IClassRule
	{
        public void Validate(ClassDeclaration was, ClassDeclaration isNow, ITypeDifference typeDifference)
		{
            if (was.IsSubclass)
			{
				// has subclass now changed ???
				if (isNow.IsSubclass)
				{
                    if (was.BaseType != isNow.BaseType)
					{
						typeDifference.IdentifiedChange(
                            new BinaryTypeChange(
                                TypeChangeReason.TypeInheritance,
                                was.BaseType,
                                isNow.BaseType,
                                new BaseTypeChangeMessageProvider(was.BaseType, isNow.BaseType)
                                ));
					}
				}
				else
				{
					typeDifference.IdentifiedChange(
                        new BinaryTypeChange(
                            TypeChangeReason.TypeInheritance,
                            was.BaseType,
                            isNow.BaseType,
                            new BaseTypeChangeMessageProvider(was.BaseType)
                            ));
				}
			}
		}

	}
}
